package com.zyx.javademo.nio.buffer;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @author Yaxi.Zhang
 * @since 2021/9/17 16:06
 */
public class BufferMethodDemo {

    public static void main(String[] args) {
        // 创建FileChannel
        try (RandomAccessFile raf = new RandomAccessFile("input/nio/read01.txt", "rw");
             FileChannel fileChannel = raf.getChannel()) {
            // 创建Buffer
            ByteBuffer buf = ByteBuffer.allocate(128);

            // 将数据写入到buffer中
            final int bufRead = fileChannel.read(buf);

            System.out.println("读入长度:" + bufRead);
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());

            // 写状态转化为读状态
            buf.flip();
            System.out.println("========================");
            System.out.println("调用buffer的flip方法" + bufRead);
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());

            System.out.println("========================");
            System.out.println("读取buffer中内容");
            System.out.println((char) buf.get());
            System.out.println((char) buf.get());
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());

            // rewind方法: 将 position 设回 0, 重读 Buffer 中的所有数据
            System.out.println("========================");
            System.out.println("调用buffer的rewind方法");
            buf.rewind();
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());

            System.out.println((char) buf.get());
            System.out.println((char) buf.get());

            // clear方法: 将 position 设回 0, 重读 Buffer 中的所有数据
            // 与rewind方法的区别在于 limit=capacity
            // clear不会清空数据
            System.out.println("========================");
            System.out.println("调用buffer的clear方法");
            buf.clear();
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());
            System.out.println((char) buf.get());

            /*
                compact()方法将所有未读的数据拷贝到 Buffer 起始处
                然后将position 设到最后一个未读元素正后面
                与clear共同使用时由于remaining值比buffer中实际剩余的字符串更多, 会导致拷贝空串
                    System.arraycopy(hb, ix(position()), hb, ix(0), remaining())
                    position(remaining())
                    limit(capacity())
                    remaining() ==> limit - position
             */
            System.out.println("========================");
            System.out.println("调用buffer的compact方法");
            // 由于原buffer的limit信息已经清空, 重新拷贝一份
            fileChannel.read(buf);
            System.out.println((char) buf.get());
            System.out.println((char) buf.get());
            buf.compact();
            System.out.println("position:" + buf.position());
            System.out.println("capacity:" + buf.capacity());
            System.out.println("limit:" + buf.limit());
            System.out.println((char) buf.get());

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}
